#include <string>
#include <iostream>
class Dog {
    public:
    Dog(std::string name = "Dummy", int age = 0):name_(name), age_(age){
    };
    void setAge(int &age) {
        std::cout << "setAge called " << age << std::endl;
        age_ = age;
    }
    void setAge(const int &age){
        std::cout << "setAge const called " << age << std::endl;
        age_ = age;
    }

    void showName() const {
        const_cast<Dog *>(this)->show_time_ += 1;
        std::cout << "showName const called" << std::endl;
    }
    void showName() {
        std::cout << "showName called" << std::endl;
    }

    /*
    1. the return value of fun is a constant pointer pointing to a constant integer value
    2. the parameter of fun is a reference of a constant pointer pointing to a constant integer
    the reference cannot refer to a different pointer (nature of references)
    the referred pointer cannot point to a different value
    */
    const int * const fun(const int * const &p) const {
        std::cout << "enter fun is p: " << *p << std::endl;
        const int b = 25;
        const int *const a = &b;
        return a;
    }

    private:
    // mutable类型的属性可以在const类的function中被改变，如果不适用mutable的话，可以使用const_cast
    // mutable int show_time;
    int show_time_;
    std::string name_;
    int age_;
};

int getAge (){
    return 30;
}

int main()
{
    Dog d;
    d.showName();
    const Dog d2;
    d2.showName();
    int a = 3;
    d.setAge(a);
    // 如果参数是rvalue，那么调用的是const类型的引用，否则调用的是非const类型的引用
    d.setAge( 3 + 5);
    d.setAge(getAge());

    // 改变const类型数据的方法
    const int &a_ref = a;
    const_cast<int &>(a_ref) = 5;

    const int temp_const = 1205;
    const int * const a_const = &temp_const;
    d.fun(a_const);
    return 0;
}
